package com.niuwa.p2p.service.impl.message;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.constant.SmsStatusEnum;
import com.niuwa.p2p.core.enums.MessageTemplateEnum;
import com.niuwa.p2p.core.enums.MsgSourceEnum;
import com.niuwa.p2p.core.mvc.entity.JsonResult;
import com.niuwa.p2p.core.utils.DateUtil;
import com.niuwa.p2p.core.utils.DictConstant;
import com.niuwa.p2p.core.utils.EmptyUtil;
import com.niuwa.p2p.core.utils.SequenceEnum;
import com.niuwa.p2p.dao.customer.CustomerDao;
import com.niuwa.p2p.dao.message.CustMsgSetDao;
import com.niuwa.p2p.dao.message.MessageDao;
import com.niuwa.p2p.dao.message.MsgTemplateDao;
import com.niuwa.p2p.entity.message.AppReceiver;
import com.niuwa.p2p.entity.message.CustMsgSet;
import com.niuwa.p2p.entity.message.Message;
import com.niuwa.p2p.entity.message.MsgTemplate;
import com.niuwa.p2p.service.mail.SimpleMailSenderService;
import com.niuwa.p2p.service.message.ISendMsgService;
import com.niuwa.p2p.service.messageTemplate.IMessageTemplateService;
import com.niuwa.p2p.service.sequence.ISequenceService;
import com.niuwa.p2p.service.sms.SmsService;
/**
 * 消息发送接口实现
 * @author money
 *
 */
@Service
public class SendMsgServiceImpl implements ISendMsgService{
	private Logger log = Logger.getLogger(SendMsgServiceImpl.class);
	@Autowired
	private CustMsgSetDao custMsgSetDao;
	@Autowired
	private MsgTemplateDao msgTemplateDao;
	@Autowired
	private MessageDao messageDao;
	@Autowired
	private CustomerDao customerDao;
	
	@Autowired
	IMessageTemplateService messageTemplateService;
	
	@Autowired
	ISequenceService sequenceService;
	
	@Autowired
	private SmsService smsService;//短信
	
	@Autowired
	@Qualifier("newMessageApi")
	private MessageApi messageApi;//消息推送
	
    @Autowired
	private SimpleMailSenderService simpleMailSenderService;//邮件发送
	
	@Override
	public void p2pSendMsg(long custId, String custName, String tel,
			String email,String extraMsg,boolean isVoiceSMS, MessageTemplateEnum template,
			Map<MsgSourceEnum, Object> sourceMap) {
		MsgTemplate  msgTemplate = msgTemplateDao.selectByPrimaryKey(template.getCode());
		//1.获取发送规则
		String[] sendMethods = getP2PSendMethods(custId, template,msgTemplate);
		//2.获取发送消息
		Map<String,String> map = messageTemplateService.fetchMessageTemplateContentByType(template, sendMethods, sourceMap);
		//Map<String,String>  map = getTestData();
		//3.生成消息
		sendP2PMsg(msgTemplate, custId, custName, tel, email, sendMethods, map,extraMsg,isVoiceSMS);
	}
	@Override
	public void appSendMsg(long custId, String custName, String tel,
			String email,String extraMsg,List<AppReceiver> receiverList, MessageTemplateEnum template) {
		//得到模板
		MsgTemplate  msgTemplate = msgTemplateDao.selectByPrimaryKey(template.getCode());
		//发送方式
		String[] sendMethods = getAppOrMcMethods(msgTemplate);
		//获取相应发送方式内容
		sendAppMsg(msgTemplate, custId, custName, tel, email, extraMsg, sendMethods, receiverList, template);
	}
	@Override
	public void mcSendMsg(long id, String name, String email, String tel,
			String extraMsg,MessageTemplateEnum template, Map<MsgSourceEnum, Object> sourceMap) {
		MsgTemplate  msgTemplate = msgTemplateDao.selectByPrimaryKey(template.getCode());
		String[] sendMethods = getAppOrMcMethods(msgTemplate);
		Map<String,String> map = messageTemplateService.fetchMessageTemplateContentByType(template, sendMethods, sourceMap);
		//Map<String,String>  map = getTestData();
		sendP2PMsg(msgTemplate, id, name, tel, email, sendMethods, map, extraMsg,false);
	}
	@Override
	public boolean reSendMsg(long id) {
		boolean flag = false;
		Message message = messageDao.selectByPrimaryKey(id);
		MsgTemplate msgTemplate = msgTemplateDao.selectByPrimaryKey(message.getMsgTempNo());
		if(message != null && msgTemplate != null){
			String sendMethod = message.getSendMethod();
			if(DictConstant.MSG_SEND_METHOD.EMAIL.getCode().equals(sendMethod)){//邮件
				flag = sendEmail(message.getTargetAddress(), msgTemplate.getTitle(), message.getContent());
			}else if(DictConstant.MSG_SEND_METHOD.IN_MSG.getCode().equals(sendMethod)){//站内信
				// do nothing
			}else if(DictConstant.MSG_SEND_METHOD.SMS.getCode().equals(sendMethod)){//短信
				flag = sendSMS(message.getTargetAddress(), message.getContent(),false);
			}
		}else{
			log.info("未查找到消息对应模板!");
		}
		if(flag){//重新发送成功，修改记录状态
			message.setSendStatus(DictConstant.SEND_STATUS.SENT.getCode());
			messageDao.updateByPrimaryKeySelective(message);
		}
		return flag;
	}
	/**
	 * 封装app消息并保存、推送
	 */
	private void sendAppMsg(MsgTemplate  msgTemplate,long custId,String custName,String tel,String email,String extraMsg,String[] sendMethods,List<AppReceiver> receiverList, MessageTemplateEnum template){
		String title = msgTemplate.getTitle();//消息标题
		if(receiverList != null && receiverList.size() > 0){//消息接收者
			for(AppReceiver appreceiver : receiverList){
				//获取接收内容
				Map<String,String> map = messageTemplateService.fetchMessageTemplateContentByType(template, sendMethods, appreceiver.getSourceMap());
				//Map<String,String>  map = getTestData();
				//根据发送方式发送
				if(sendMethods != null && sendMethods.length > 0){
					for(String method : sendMethods){//目前发送方式只有一种
						String sendMsgContext =  map.get(method);//发送消息内容
						Message message = new Message();
						boolean isSuccess = true;
						if(DictConstant.MSG_SEND_METHOD.SMS.getCode().equals(method)){//短信
							isSuccess = sendSMS(appreceiver.getReciverTel(),sendMsgContext,false);
							message.setTargetAddress(appreceiver.getReciverTel());
						}else if(DictConstant.MSG_SEND_METHOD.EMAIL.getCode().equals(method)){//邮件[app时这种方式不会出现、暂时保留]
							//isSuccess = sendEmail();
							message.setTargetAddress(appreceiver.getReciverEmail());
						}else{//站内消息进行推送
							messageApi.pushMessage(String.valueOf(appreceiver.getReceiverSeqNo()), title, sendMsgContext, msgTemplate.getTempNo(), extraMsg);
						}
						message.setMsgNo(getMsgNo());
						message.setMsgTempNo(msgTemplate.getTempNo());
						message.setSendMethod(method);
						message.setContent(sendMsgContext);
						if(isSuccess){
							message.setSendStatus(DictConstant.SEND_STATUS.SENT.getCode());
						}else{
							message.setSendStatus(DictConstant.SEND_STATUS.SEND_FAIL.getCode());
						}
						message.setPlatformType(msgTemplate.getPlatformType());
						message.setMsgKind(msgTemplate.getMsgKind());
						message.setReceiverName(appreceiver.getReciverName());
						message.setReceiver(appreceiver.getReceiverId());
						message.setSender(custId);//消息发送方
						message.setSenderName(custName);
						message.setIsValid("Y");
						message.setIsRead("N");
						message.setMemo(extraMsg);//消息备注
						message.setLastValidTime(null);//消息最后有效期
						message.setCreateTime(new Date());
						message.setUpdateTime(null);//消息修改时间
						message.setReceiverSeqNo(appreceiver.getReceiverSeqNo());
						sendInMsg(message);
					}
				}
			}
		}
		
	}
	
	/**
	 * 封装p2p消息并保存
	 */
	private void sendP2PMsg(MsgTemplate  msgTemplate,long custId,String custName,String tel,String email,String[] sendMethods,Map<String,String> map,String extraMsg,boolean isVoiceSMS ){
		if(sendMethods != null && sendMethods.length > 0){
			for(String method : sendMethods){
				String sendMsgContext =  map.get(method);//发送消息内容
				Message message = new Message();
				boolean isSuccess = true;
				if(DictConstant.MSG_SEND_METHOD.SMS.getCode().equals(method)){//短信
					isSuccess = sendSMS(tel,sendMsgContext,isVoiceSMS);
					message.setTargetAddress(tel);
				}else if(DictConstant.MSG_SEND_METHOD.EMAIL.getCode().equals(method)){//邮件
					isSuccess = sendEmail(email,msgTemplate.getTitle(),sendMsgContext);
					message.setTargetAddress(email);
				}
				message.setMsgNo(getMsgNo());
				message.setMsgTempNo(msgTemplate.getTempNo());
				message.setSendMethod(method);
				message.setContent(sendMsgContext);
				if(isSuccess){
					message.setSendStatus(DictConstant.SEND_STATUS.SENT.getCode());
				}else{
					message.setSendStatus(DictConstant.SEND_STATUS.SEND_FAIL.getCode());
				}
				message.setPlatformType(msgTemplate.getPlatformType());
				message.setMsgKind(msgTemplate.getMsgKind());
				message.setReceiverName(custName);
				message.setReceiver(custId);
				message.setSender(null);//消息发送方
				message.setSenderName(null);
				message.setIsValid("Y");
				message.setIsRead("N");
				message.setMemo(extraMsg);//消息备注
				message.setLastValidTime(null);//消息最后有效期
				message.setCreateTime(new Date());
				message.setUpdateTime(null);//消息修改时间
				sendInMsg(message);
			}
		}
	}
	
	/**
	 * 发送邮件
	 * @return
	 */
	private boolean sendEmail(String reciverEmail,String subject,String content){
		boolean result = simpleMailSenderService.send(reciverEmail, subject, content);
		if(!result){//发送失败，连发3次
			int count = 3;
			while(count > 0 && !result){
				try {
					Thread.sleep(1000);
					result = simpleMailSenderService.send(reciverEmail, subject, content);
					count--;
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	/**
	 * 发送短信
	 * @return
	 */
	private boolean sendSMS(String tel,String content,boolean isVoiceSMS){
		boolean result = false;
		SmsStatusEnum smsStatusEnum = null;
		if(isVoiceSMS){//发送语音短信
			smsStatusEnum=smsService.sendAudio(tel, null, content);
		}else{
			smsStatusEnum=smsService.sendBatchMessage(tel,content);
		}
		if(smsStatusEnum.getValue() == 0){//发送成功
			result = true;
		}
		if(!result){//如果消息发送失败
			int count = 3;//失败后连续发送3次，5次太多
			while(count > 0 && !result){
				try {
					Thread.sleep(1000);
					SmsStatusEnum smsEnum = null;
					if(isVoiceSMS){//发送语音短信
						smsEnum=smsService.sendAudio(tel, null, content);
					}else{
						smsEnum=smsService.sendBatchMessage(tel,content);
					}
					if(smsEnum.getValue() == 0){//发送成功
						result = true;
					}
					count--;
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}
	/**
	 * 发送站内信
	 * @return
	 */
	private void sendInMsg(Message message){
		messageDao.insert(message);
	}
	/**
	 * 获取p2p消息发送方式
	 * @param custId
	 * @param template
	 * @return
	 */
	private String[] getP2PSendMethods(long custId,MessageTemplateEnum template,MsgTemplate msgTemplate){
		String[] sendMethods = {};
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("custId", custId);
		map.put("msgTempNo", template.getCode());
		CustMsgSet custMsgSet = custMsgSetDao.getUserSetSendMethod(map);
		if(custMsgSet == null){//用户未设置自定义
			if(msgTemplate != null){
				String sendMethod = msgTemplate.getSendMethod();
				if(sendMethod != null && !"".equals(sendMethod)){
					sendMethods = sendMethod.split(",");
				}
			}
		}else{
			String methodsString = custMsgSet.getSendMethod();
			if(methodsString != null && !"".equals(methodsString)){
				sendMethods = methodsString.split(",");
			}
		}
		return sendMethods;
	}
	
	/**
	 * 获取app或者mc消息发送方式
	 * @param template
	 * @return
	 */
	private String[] getAppOrMcMethods(MsgTemplate msgTemplate){
		String[] sendMethods = {};
		if(msgTemplate != null){
			String sendMethod = msgTemplate.getSendMethod();
			if(sendMethod != null && !"".equals(sendMethod)){
				sendMethods = sendMethod.split(",");
			}
		}
		return sendMethods;
	}
	/**
	 * 获取消息编号
	 * @return
	 */
	private String getMsgNo(){
		String result = "";
		try {
			result = sequenceService.getCompleteSequenceBySeqKey(SequenceEnum.XX.getCode(), SequenceEnum.XX.getLength());//XX0000000001
		} catch (Exception e) {
			log.info("生成消息编号失败!");
		}
		return result;
		
	}
	private Map<String,String> getTestData(){
		Map<String,String>  map = new HashMap<String,String>();
		map.put("IN_MSG", "站内消息内容");
		map.put("SMS", "短信消息内容【牛娃金融】");
		map.put("EMAIL", "邮件发送内容");
		return map;
	}
	
	/**
	 * 校验验证码
	 */
	@Override
	public JsonResult verifySmsCode(String mobile,String code,String platformType,String sendMethod,boolean flag) {
		JsonResult json = new JsonResult();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("mobile", mobile);
		map.put("platformType", platformType);
		map.put("sendMethod", sendMethod);
		Message message = messageDao.selectByParam(map);
		json.setSuccess(false);
		if(EmptyUtil.isNotEmpty(message)){
			//判断是否过期
			if(DateUtil.addMinutes(message.getCreateTime(), 30).after(new Date())){
				if(code.equals(message.getMemo())){
					if(flag){
						//更新
						message.setUpdateTime(new Date());
						message.setIsRead("Y");
						messageDao.updateByPrimaryKeySelective(message);
					}
					json.setSuccess(true);
					json.setMsg("成功");
				} else {
					json.setMsg("验证码不正确");
				}
			} else {
				json.setMsg("验证码已过期");
			}
		} else {
			json.setMsg("验证码不存在");
		}
		return json;
	}
	
}
